package tcln.gxtx.client.widget.treegrid;

import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.store.TreeStoreEvent;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.treegrid.EditorTreeGrid;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel.Joint;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.AbstractImagePrototype;

/**
 * An extended treegrid which enables the client application to perform several actions: remove FOLDER/leaf icon style,
 * handle row over/out events...
 * 
 * @param <M>
 *            the model type
 * @author Truong Chau Lien Ngoc (lienngoc@gmail.com)
 */
public class ExtendedEditorTreeGrid<M extends ModelData> extends EditorTreeGrid<M> implements TreeGridExtension<M> {

    /**
     * A flag indicating that the icon styles for opening/closing/leaf nodes should NOT be rendered.
     */
    private boolean nodeIconStyleHidden;

    /**
     * @param store
     * @param cm
     */
    public ExtendedEditorTreeGrid(final TreeStore<M> store, final ColumnModel cm) {
        super(store, cm);
        setView(new ExtendedTreeGridView<M>());
        editSupport = new ExtendedEditorSupport<M>();
        editSupport.bind(this);
    }

    /**
     * Returns a model data at a given visible row.
     * 
     * @param rowIndex
     * @return
     */
    public M getModelAtRow(int rowIndex) {
        return getTreeView().getListStore().getAt(rowIndex);
    }
    
    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    @Override
    public ExtendedTreeGridView<M> getTreeView() {
        return (ExtendedTreeGridView<M>) super.getTreeView();
    }

    /**
     * Handles when a given row is 'OVER' (i.e. the mouse hovers on that row).
     * 
     * @param model
     *            Model data corresponding to given row.
     * @param row
     *            Row element (HTMLElement).
     * @param rowIndex
     *            Row index.
     */
    protected void onRowOver(M model, Element row, int rowIndex) {
        // no special handling is needed
    }

    /**
     * Handles when a given row is 'OUT' (i.e. the mouse is moved out of that row).
     * 
     * @param model
     *            Model data corresponding to given row.
     * @param row
     *            Row element (HTMLElement).
     * @param rowIndex
     *            Row index.
     */
    protected void onRowOut(M model, Element row, int rowIndex) {
        // no special handling is needed
    }

    /**
     * {@inheritDoc}
     */
    public void setNodeIconStyleHidden(boolean nodeIconStyleHidden) {
        this.nodeIconStyleHidden = nodeIconStyleHidden;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Joint calcualteJoint(final M model) {
        return super.calcualteJoint(model);
    };

    /**
     * {@inheritDoc}
     */
    @Override
    public AbstractImagePrototype calculateIconStyle(final M model) {
        if (nodeIconStyleHidden) {
            return null;
        }
        return super.calculateIconStyle(model);
    };

    /**
     * Searches for a tree node ID (generated on adding nodes).
     * 
     * @param m
     * @return
     */
    public String findNodeId(final M m) {
        if (m == null) {
            return null;
        } else if (treeStore.getKeyProvider() != null) {
            return generateModelId(m);
        } else {
            return cache.get(m);
        }
    };

    /**
     * {@inheritDoc}
     */
    @Override
    public TreeNode findNode(M m) {
        return super.findNode(m);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onDataChanged(TreeStoreEvent<M> se) {
        super.onDataChanged(se);
        ExtendedTreeGrid.statefulExpandAll(this, treeStore);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onAfterRenderView() {
        super.onAfterRenderView();
        ExtendedTreeGrid.statefulExpandAll(this, treeStore);
    }
}
